package com.example.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 一个标准的 MyBatis-Plus 配置类，它的主要作用是：
 * 启用分页插件，使得你的数据库查询可以自动支持分页功能，并指定使用的是 MySQL 数据库类型。
 *
 * @Configuration 注解的类本身会被 Spring 容器扫描并注册为一个 Bean 对象。
 * @Bean 注解的方法会被 Spring 识别，并将其返回值对象注册为容器中的 Bean。
 * <p></p>
 * ✅ @Component 是用于注册“类”级的 Bean，@Bean 是用于注册“方法返回值”级的 Bean，而 @Configuration 本身是一个特殊的 @Component，用于承载多个 @Bean 方法，并保证它们在容器中作为单例注册。
 * 通常我们在配置类中还会加上 @ComponentScan 来统一扫描其他包中的组件类并注册为 Bean。
 */

/**
 * 表示这是一个 配置类
 * 会被 Spring 容器扫描并执行，相当于以前的 applicationContext.xml 配置文件
 */
@Configuration
public class MybatisConfig {
    /**
     * 表示这个方法的返回值将被 Spring 托管为 Bean
     * 其他地方自动生效（例如 MyBatis 的核心配置中会自动注入此拦截器）
     *
     * @return
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        /**
         * 这是 MyBatis-Plus 的“插件容器”
         * 可以往里面添加各种功能插件，例如分页、乐观锁、防止全表更新等
         */
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        /**
         * 表示添加一个 分页插件
         * 指定数据库类型为 MySQL（⚠️ 不指定类型可能分页语法不兼容）
         * 它会拦截所有分页相关的查询 SQL，自动拼接 LIMIT 和 OFFSET 子句
         */
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}
/**
 * Spring Boot 启动时扫描 @Configuration
 * ↓
 * 创建 MybatisPlusInterceptor Bean
 * ↓
 * 注册 PaginationInnerInterceptor（分页）
 * ↓
 * MyBatis-Plus 执行分页查询时被拦截
 * ↓
 * SQL 自动拼接 LIMIT 分页语句
 * ↓
 * 返回分页结果 Page<T>
 * <p></p>
 * @Configuration 是 Spring 中用于标记 配置类 的注解，表示这个类中可能包含一个或多个 @Bean 方法，用于定义 Bean 对象，并注册到 Spring 容器中。
 * 特性                               | 描述
 * 被 @Component 修饰，支持组件扫描      | 所以也可以通过 @ComponentScan 被自动注册
 * 支持方法级别的 @Bean 定义             | 把普通 Java 方法的返回值注册为 Spring Bean
 * 默认是 单例模式                      | 方法只执行一次，Bean 被 Spring 容器托管
 * <p></p>
 * @Bean 注解标注在方法上，表示这个方法的返回值是一个要被 Spring 管理的 Bean，加入到容器中。
 * Bean 之间依赖注入时，@Configuration 会保证是单例
 * <p></p>
 * Spring 做的事情是：
 * 启动时扫描 @Configuration 类
 * 执行类中的 @Bean 方法，并将返回值注册为一个 Bean
 * 默认保持方法只执行一次（遵守单例模式）
 * @Configuration 是用于声明配置类的注解，配合 @Bean 让方法返回值注册为 Spring 容器中的 Bean；
 * 虽然 @Bean 可单独使用，但建议在规范化配置类时总是加上 @Configuration，以获得更强的单例保障与代理能力。
 * <p></p>
 * 项目                           | @Configuration       | 普通 @Component
 * 本类是否注册为 Bean？            | ✅ 是                | ✅ 是
 * @Bean 方法是否被增强为单例？      | ✅ 是（代理拦截）      | ❌ 否（每次调用重新执行）
 * 是否保证内部依赖是单例共享？       | ✅ 是                | ❌ 否，可能产生多个对象
 * 是否被 CGLIB 动态代理？          | ✅ 是（生成代理类）    | ❌ 否
 */

